package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class TestService {

    public static final int DB_COUNT = 10;
    public static final int TABLE_COUNT = 4;

    /**
     * 思路1：独立hash
     * GetTableIdx 根据用户 ID 获取分库分表索引
     */
    public void getTableIdx1(Long uid) {
        int code = uid.hashCode();
        int dbIndex = code % DB_COUNT;
        int tableIndex = code % TABLE_COUNT;
        System.out.println("dbIndex=" + dbIndex + ", tableIndex=" + tableIndex);
    }

    /**
     * 思路3：二次分片hash
     * 思路二中整体思路正确，只是最后计算库序号和表序号的时候，使用了库数量作为影响表序号的因子，
     * 导致扩容时表序号偏移而无法进行。事实上，我们只需要换种写法，就能得出一个比较大众化的分库分表方案。
     */
    public void getTableIdx3(Long uid) {
        // ①算Hash
        int code = uid.hashCode();
        // ②分片序号
        int slot = code % (DB_COUNT * TABLE_COUNT);
        // ③重新修改二次求值方案
        int dbIndex = slot / TABLE_COUNT;
        int tableIndex = slot % TABLE_COUNT;
        System.out.println("[getTableIdx3] uid=" + uid +",slot=" + slot + ",dbIndex=" + dbIndex + ",tableIndex=" + tableIndex);
    }

    /**
     * 数据库扩容2倍
     */
    public void getTableIdxEven(Long uid) {
        // ①算Hash
        int code = uid.hashCode();
        // ②分片序号
        int slot = code % (2 * DB_COUNT * TABLE_COUNT);
        // ③重新修改二次求值方案
        int dbIndex = slot / TABLE_COUNT;
        int tableIndex = slot % TABLE_COUNT;
        System.out.println("[getTableIdxEven] uid=" + uid +",slot=" + slot + ", dbIndex=" + dbIndex + ", tableIndex=" + tableIndex);
    }

    public void getTableIdxOdd(Long uid) {
        // ①算Hash
        int code = uid.hashCode();
        // ②分片序号
        int slot = code % ((2 * DB_COUNT + 1) * TABLE_COUNT);
        // ③重新修改二次求值方案
        int dbIndex = slot / TABLE_COUNT;
        int tableIndex = slot % TABLE_COUNT;
        System.out.println("[getTableIdxOdd] uid=" + uid +",slot=" + slot + ", dbIndex=" + dbIndex + ", tableIndex=" + tableIndex);
    }
}
